using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml.Serialization;
using Microsoft.SharePoint;
#if SP_Server
using Microsoft.SharePoint.Publishing;
#endif
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint.WebPartPages;

namespace DE.Sdc.SharePoint.SPContentStructure.Import
{
    [Serializable]
    [XmlType(AnonymousType = true, Namespace = DeploymentConstants.Namespace)]
    [XmlRoot(Namespace = DeploymentConstants.Namespace, IsNullable = false)]
    public class Page : File
    {
        public Page()
        {
            WebParts = new List<WebPart>();
        }

        /// <remarks/>
        [XmlArrayItem("WebPart")]
        public List<WebPart> WebParts { get; set; }

        /// <remarks/>
        [XmlAttribute]
        public bool IsDefault { get; set; }

        /// <remarks/>
        [XmlAttribute]
        public bool RemoveAllWebParts { get; set; }

        /// <summary>
        /// Modifies the properties for a file
        /// </summary>
        /// <param name="file">The file which properties should updated</param>
        /// <param name="changeFileLevel"></param>
        /// <param name="parentFolder"></param>
        public override void ImportDefinition(SPFile file, SPFolder parentFolder, bool changeFileLevel)
        {
            Trace.WriteLine("Try to modify page '" + Item.Title + "' with url '" + Item.AbsoluteUrl + "'.",
                            "ContentStructureImporter:Modify");
            base.ImportDefinition(file, parentFolder, false);
            file = UpdatedSPObject;

            SPLimitedWebPartManager webPartManager = null;

            try
            {
                if (RemoveAllWebParts || WebParts != null && WebParts.Count > 0)
                {
                    Checkout(file);
                    webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);

                    if (RemoveAllWebParts)
                    {
                        for (int index = 0; index < webPartManager.WebParts.Count; index++)
                        {
                            webPartManager.DeleteWebPart(webPartManager.WebParts[index]);
                            index--;
                        }
                    }

                    if (WebParts != null && WebParts.Count > 0)
                    {
                        DeploymentHelper.CreateContext(DeploymentContext.Current.ReceiverWeb.Url +
                                                       "/_layouts/ManageFeatures.aspx?Scope=Site");

                        for (int index = 0; index < WebParts.Count; index++)
                        {
                            WebPart webPartDefinition = WebParts[index];
                            webPartDefinition.Title = DeploymentHelper.Resolve(webPartDefinition.Title,
                                                                          file.ParentFolder.ParentWeb.Locale);
                            System.Web.UI.WebControls.WebParts.WebPart webPart = webPartManager.WebParts[webPartDefinition.Title];

                            if (webPart == null)
                            {
                                for (int i = 0; i < webPartManager.WebParts.Count; i++)
                                {
                                    System.Web.UI.WebControls.WebParts.WebPart currentWebPart = webPartManager.WebParts[i];

                                    if (currentWebPart.Title == webPartDefinition.Title)
                                        webPart = currentWebPart;
                                }
                            }

                            DeploymentContext.Current.WebPartDefinition = webPartDefinition;
                            webPartDefinition.ImportDefinition(webPart, webPartManager);
                        }

                        DeploymentHelper.ClearContext();

                        file.Update();
                    }
                }
            }
            finally
            {
                if (webPartManager != null)
                    webPartManager.Dispose();
            }

            if (IsDefault)
            {
                bool defaultSet = false;
                #if SP_Server
                try
                {
                    PublishingWeb web = PublishingWeb.GetPublishingWeb(file.ParentFolder.ParentWeb);
                    if (web.DefaultPage == null || web.DefaultPage.Url != file.Url)
                    {
                        web.DefaultPage = file;
                        web.Update();

                        defaultSet = true;
                    }
                }
                catch (TypeLoadException ex)
                {
                    Trace.WriteLine("Error on modifing file '" + Item.Title + "' with url '" + Item.AbsoluteUrl + "'.",
                                    "ContentStructureImporter:ModifyFile");
                    Trace.WriteLine(ex.Message, "ContentStructureModifier:ModifyFile");
                }
                catch (InvalidPublishingWebException ex)
                {
                    Trace.WriteLine("Error on modifing file '" + Item.Title + "' with url '" + Item.AbsoluteUrl + "'.",
                                    "ContentStructureImporter:ModifyFile");
                    Trace.WriteLine(ex.Message, "ContentStructureModifier:ModifyFile");
                }
                #endif
    
                if (defaultSet == false)
                {
                    using (var site = new SPSite(DeploymentContext.Current.Web.Site.Url))
                    {
                        using (var web = site.OpenWeb(DeploymentContext.Current.Web.ServerRelativeUrl))
                        {
                            var folder = web.RootFolder;
                            folder.WelcomePage = file.Url;
                            folder.Update();
                        }
                    }
                }
            }

            if (changeFileLevel)
                ChangeFileLevel(file, Item);

            Trace.WriteLine("File '" + Item.Title + "' with url '" + Item.AbsoluteUrl + "' modified.",
                            "ContentStructureImporter:ModifyFile");
        }
    }
}